package com.tools.cleanmaster.ui.view;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Paint.Cap;
import android.graphics.Paint.FontMetrics;
import android.graphics.Paint.Style;
import android.graphics.Path;
import android.graphics.Rect;
import android.graphics.Shader;
import android.graphics.Shader.TileMode;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import android.view.animation.LinearInterpolator;

import com.hm.base.android.ui.util.ScreenUtil;
import com.nineoldandroids.animation.Animator;
import com.nineoldandroids.animation.AnimatorListenerAdapter;
import com.nineoldandroids.animation.ValueAnimator;
import com.tools.ad.util.FontUtils;
import com.tools.cleanmaster.R;

/**
 * desc:
 * date: 2018/3/2
 * author: ancun
 */

public class SlideUnlockHintView extends View {

    private static final int ANIM_DURATION = 1600;
    private static final int ARROW_COUNT = 3;

    // 原来是两像素，现在修改为1dp
    private static int ARROW_STROKE_WIDTH;
    private static int ARROW_WIDTH;
    private static int ARROW_HEIGHT;
    private static int ARROW_TEXT_PADDING;
    private static int TEXT_SIZE_DEFAULT;
    private static int ADJUEST_SIZE;
    private static final float[] GRADIENT_POSITIONS = new float[]{
            0, 0.3f, 1
    };
    private static final int[] GRADIENT_COLORS = new int[]{
            0xe6ffffff, 0x30ffffff, 0x30ffffff
    };
    private Paint mGradientPaint;
    private Shader mInitGradient;
    private ValueAnimator mGradientAnimator;
    private Matrix mGradientOffsetMatrix;
    private Path[] mArrowPaths;
    private String mHintText;
    private Rect mHintTextBounds;
    private FontMetrics mFontMetrics;
    private int mHintTextStartX = 0;
    private int mHintTextStartY = 0;

    private int mMeasuredWidth;
    private int mMeasuredHeight;
    private int mContentWidth;

    private Context mContext;
    private boolean mIsStarted;
    private SUHandler mHandler;

    private class SUHandler extends Handler {
        static final int MSG_ANIM = 1;
        static final int DELAY_ANIM = 1600; //动画间隔时间，单位：毫秒

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_ANIM:
                    start();
                    break;
            }
        }
    }

    public SlideUnlockHintView(Context context) {
        super(context);
        init(context, null);
    }

    public SlideUnlockHintView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    private void init(Context context, AttributeSet attrs) {
        mContext = context;
        mHandler = new SUHandler();
        ARROW_STROKE_WIDTH = ScreenUtil.dp2px(mContext, 1);
        ARROW_WIDTH = ScreenUtil.dp2px(mContext, 10);
        ARROW_HEIGHT = ScreenUtil.dp2px(mContext, 18);
        ARROW_TEXT_PADDING = ScreenUtil.dp2px(mContext, 8);
        TEXT_SIZE_DEFAULT = ScreenUtil.dp2px(mContext, 22);
        ADJUEST_SIZE = ScreenUtil.dp2px(mContext, 14);

        mGradientPaint = new Paint();
        mGradientPaint.setAntiAlias(true);

        mGradientPaint.setStrokeCap(Cap.ROUND);
        mGradientPaint.setStrokeWidth(ARROW_STROKE_WIDTH);
        mGradientPaint.setStyle(Style.STROKE);
        mGradientOffsetMatrix = new Matrix();

        mArrowPaths = new Path[ARROW_COUNT];

        ValueAnimator va = ValueAnimator.ofFloat(0, 1);
        va.setDuration(ANIM_DURATION);
        va.setInterpolator(new LinearInterpolator());
        va.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator animator) {
                if (mInitGradient == null) {
                    return;
                }
                float animationProgress = (Float) animator.getAnimatedValue();
                setGradientPositionByProgress(animationProgress);
                invalidate();
            }
        });
        va.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                if (null != mHandler && mIsStarted) {
                    mHandler.sendEmptyMessageDelayed(SUHandler.MSG_ANIM, SUHandler.DELAY_ANIM);
                }
            }
        });

        mGradientAnimator = va;

        // 获取文字相关的信息
        mHintTextBounds = new Rect();
        mGradientPaint.setStyle(Style.FILL);
        if (attrs == null) {
            mGradientPaint.setTextSize(ScreenUtil.dp2px(mContext, 20));
            mGradientPaint.setColor(Color.WHITE);
        } else {
            // 读取文案的配置信息
            TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SlideUnlockHintView);
            mHintText = a.getString(R.styleable.SlideUnlockHintView_hintText);
            float hintTextSize = a.getDimension(R.styleable.SlideUnlockHintView_hintTextSize, TEXT_SIZE_DEFAULT);
            int hintColor = a.getColor(R.styleable.SlideUnlockHintView_hintTextColor, Color.WHITE);
            a.recycle();

            mGradientPaint.setTextSize(hintTextSize);
            mGradientPaint.setColor(hintColor);
        }
        mGradientPaint.setTypeface(FontUtils.getInstance(mContext).getRobotThin());
        mFontMetrics = mGradientPaint.getFontMetrics();
        if (!TextUtils.isEmpty(mHintText)) {
            mGradientPaint.getTextBounds(mHintText, 0, mHintText.length(), mHintTextBounds);
        }
    }

    private void setGradientPositionByProgress(float progress) {
        mGradientOffsetMatrix.setTranslate((mContentWidth + ADJUEST_SIZE) * progress * 3, 0);
    }

    private void updateDrawParams(int w, int h) {
        // 未知状态，什么都不做
        if (w == 0 && h == 0) {
            return;
        }

        int textWidth = mHintTextBounds.width();
        int arrowAllWith = ARROW_WIDTH + ARROW_COUNT * ARROW_STROKE_WIDTH;
        mContentWidth = arrowAllWith + textWidth > 0 ? (textWidth + ARROW_TEXT_PADDING) : 0;

        // 构建出所有需要绘制的箭头信息
        int startXPos = (mMeasuredWidth - mContentWidth) / 2 - ADJUEST_SIZE;
        int startYPos = (mMeasuredHeight - ARROW_HEIGHT) / 2;
        for (int i = 0; i < ARROW_COUNT; i++) {
            Path path = new Path();
            int arrowStartX = startXPos + i * ARROW_WIDTH;
            path.moveTo(arrowStartX, startYPos);
            path.lineTo(arrowStartX + ARROW_WIDTH, startYPos + ARROW_HEIGHT / 2);
            path.lineTo(arrowStartX, startYPos + ARROW_HEIGHT);
            mArrowPaths[i] = path;
        }

        int start = startXPos - mContentWidth - ADJUEST_SIZE;
        int end = startXPos + mContentWidth + ADJUEST_SIZE;
        mInitGradient = new LinearGradient(start, 0, end, 0, GRADIENT_COLORS, GRADIENT_POSITIONS,
                TileMode.MIRROR);
        mGradientPaint.setShader(mInitGradient);

        // 文案不为空，计算文案的显示开始区域
        if (mHintTextBounds.width() > 0 && mHintTextBounds.height() > 0) {
            mHintTextStartX = startXPos + ARROW_WIDTH * ARROW_COUNT + ARROW_TEXT_PADDING;
            mHintTextStartY = (int) ((mMeasuredHeight - mFontMetrics.bottom - mFontMetrics.top) / 2);
        }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        updateDrawParams(w, h);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int measureModeWidth = MeasureSpec.getMode(widthMeasureSpec);
        int measureModeHeight = MeasureSpec.getMode(heightMeasureSpec);

        if (measureModeWidth == MeasureSpec.EXACTLY) {
            mMeasuredWidth = MeasureSpec.getSize(widthMeasureSpec);
        } else {
            int arrowAllWidth = ARROW_WIDTH * ARROW_COUNT;
            int textWidth = mHintTextBounds.width();
            mMeasuredWidth = arrowAllWidth + textWidth > 0 ? (textWidth + ARROW_TEXT_PADDING) : 0;
        }

        if (measureModeHeight == MeasureSpec.EXACTLY) {
            mMeasuredHeight = MeasureSpec.getSize(heightMeasureSpec);
        } else {
            mMeasuredHeight = Math.max(ARROW_HEIGHT, mHintTextBounds.height());
        }
        setMeasuredDimension(mMeasuredWidth, mMeasuredHeight);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        drawArrow(canvas);
        drawHintText(canvas);
    }

    // 绘制箭头时
    private void drawArrow(Canvas canvas) {
        mInitGradient.setLocalMatrix(mGradientOffsetMatrix);
        mGradientPaint.setShader(mInitGradient);
        mGradientPaint.setStyle(Style.STROKE);
        mGradientPaint.setStrokeCap(Cap.ROUND);
        mGradientPaint.setStrokeWidth(ARROW_STROKE_WIDTH);
        for (Path path : mArrowPaths) {
            if (path != null) {
                canvas.drawPath(path, mGradientPaint);
            }
        }
    }

    private void drawHintText(Canvas canvas) {
        // 文字为空，什么都不做
        if (mHintTextBounds.height() == 0) {
            return;
        }
        mGradientPaint.setStyle(Style.FILL);
        canvas.drawText(mHintText, mHintTextStartX, mHintTextStartY, mGradientPaint);
    }

    public void destory() {
        mIsStarted = false;
        mHandler.removeCallbacksAndMessages(null);
        mGradientAnimator.end();
        mHandler = null;
    }

    public void start() {
        mIsStarted = true;
        if (!mGradientAnimator.isStarted()) {
            mGradientAnimator.start();
        }
    }

    public void stop() {
        mIsStarted = false;
        mHandler.removeCallbacksAndMessages(null);
        if (mGradientAnimator != null) {
            mGradientAnimator.end();
        }
        setGradientPositionByProgress(0);
    }
}
